<?php
/**
 * @copyright meila.com
 * @author wangtao5@
 * @name
 * @param
 */

class ml_model_guang_rdsFilter extends ml_model_redis
{
    const SINGLE_KEY_PREFFIX = 'gf_';
    const COLLECT_KEY_PREFFIX = 'gfg_';
    private $cache_time = 2400;
    private $min_amount = 60;
    private $more_key = '';
    function __construct() {
        if(!$this->init_rds('meila_guang'))
            return false;
    }

    public function get_filter_result($option, $block, $sort='')
    {
        $this->_data = null;
        $start =  $block * ML_GUANG_PAGESIZE;             //块开始位置
        $end = $start + ML_GUANG_PAGESIZE-1;              //块结束位置
        $unsort = ml_tool_tag::comb_key($option);         //拼装未排序的key
        $unsort_key = $unsort['comb_key'];                 //未排序的key
        $unsort_name = $unsort['name'];                    //单个条件的条件
        $destKey = '';                                  //最后的需要的key
        $is_had = false;                                 //是否已经存在 
        $tmp_key = '';                                    //临时key用来判断是否已经存在的
        if($unsort_name){ //单个条件key生成
            $unsort_key = self::SINGLE_KEY_PREFFIX.ml_tool_tag::single_key($unsort_name['name'], $unsort_name['value']);
        }else{
            $unsort_key = self::COLLECT_KEY_PREFFIX.$unsort_key;
        }
        
        $tmp_key = !empty($sort) ? $unsort_key.'_'.$sort : $unsort_key;
        $tmp_key = str_replace(self::SINGLE_KEY_PREFFIX, self::COLLECT_KEY_PREFFIX, $tmp_key);
        if($this->exists($tmp_key)){ //存在就结束，返回数据
            $rs = $this->get_range($tmp_key, $start, $end);
            //Tool_logger::monitorLog('guang_rdshad', 'redis | '.$destKey, Tool_logger::LOG_LEVEL_NOTICE );
            return $rs;
        }
        
        if(!$this->exists($unsort_key)){
            if (!$unsort_name){
                $rs = $this->get_rids_by_inter($option); //多个条件的碰撞
                if($rs){
                    $is_had = true;
                    $this->more_key = $unsort_key;
                }
            }
        }else{
            $is_had = true;
        }
        
        if(!$is_had){  //不存在结束
            //Tool_logger::scrib_log('meila-debug_guang_rdscount', $unsort_key.' | 0');
            return false;
        }
        
        if(!empty($sort)){ //存在排序
            $destKey = $tmp_key;
            //Tool_logger::monitorLog('guang_rdsgenerate', $destKey, Tool_logger::LOG_LEVEL_NOTICE );
            $sort_map= array('by'=>self::SINGLE_KEY_PREFFIX.'time_*','sort'=>'desc','store'=>$destKey);
            $starttime = ml_tool_time::get_microtime();
            $rs = $this->sort($unsort_key, $sort_map);
            $endtime = ml_tool_time::get_microtime();
            //$usetime = bcsub($endtime, $starttime, 6);
            //Tool_logger::debugLog('guang_rdssort', $destKey.' | '.$usetime);
            if($rs){
                $is_had = true;
                $this->expireAt($destKey , time()+$this->cache_time);
            }
        }else{
            $destKey = $unsort_key;
        }
        
        $rs = $this->get_range($destKey, $start, $end);
        
        return $rs;
    }
    function get_range($key, $start, $end){
        if(!$this->exists($key))
            return false;
        $type = $this->type($key);
        $array = array();
        $count = 0;
        switch($type){
            case 3 :
                $array = $this->lRange($key, $start, $end);
                $count = $this->lLen($key);
            break;
            case 4 :
                $array = $this->zRevRange($key, $start, $end);
                $count = $this->zSize($key);
            break;
            default:
                return false;
        }
        $this->_data = array(
            'total' => $count,
            'rids'  => $array
        );
        //if (!empty($this->more_key) && $count<$this->min_amount)
            //Tool_logger::scrib_log('meila-debug_guang_rdscount', $this->more_key.' | '.$count);
        return $array;
    }
    function get_rids_by_inter($option){
        $base_key = array();
        $rds_cnt = array();
        $add_key = array();
        $prev = '';
        if(!empty($option['ctg'])){
            $ctg_key = self::SINGLE_KEY_PREFFIX.ml_tool_tag::single_key('ctg', $option['ctg']);
            if($this->exists($ctg_key))
                $rds_cnt['ctg'] = $this->zSize($ctg_key);
            else
                return false;
            $base_key['ctg'] = array('code'=>$option['ctg']);
        }
        if(!empty($option['tag'])){
            foreach($option['tag'] as $key=>$tag){
                $tag_key = self::SINGLE_KEY_PREFFIX.ml_tool_tag::single_key($key, $tag);
                if($this->exists($tag_key))
                    $rds_cnt[$key] = $this->zSize($tag_key);
                else
                    return false;
                $base_key[$key] = array('code'=>$tag, 'sub'=>1);
            }
        }
        if(!empty($option['color'])){
            $color_key = self::SINGLE_KEY_PREFFIX.ml_tool_tag::single_key('color', $option['color']);
            if($this->exists($color_key))
                $rds_cnt['color'] = $this->zSize($color_key);
            else
                return false;
            $base_key['color'] = array('code'=>$option['color']);
        }
        if(!empty($option['sex'])){
            $sex_key = self::SINGLE_KEY_PREFFIX.ml_tool_tag::single_key('sex', $option['sex']);
            if($this->exists($sex_key))
                $rds_cnt['sex'] = $this->zSize($sex_key);
            else
                return false;
            $base_key['sex'] = array('code'=>$option['sex']);
        }
        if(!empty($option['price'])){
            $price_key = self::SINGLE_KEY_PREFFIX.ml_tool_tag::single_key('price', $option['price']);
            if($this->exists($price_key))
                $rds_cnt['price'] = $this->zSize($price_key);
            else
                return false;
            $base_key['price'] = array('code'=>$option['price']);
        }
        asort($rds_cnt, SORT_NUMERIC);
        foreach($rds_cnt as $name=>$cnt){
            $cur_code = $base_key[$name]['code'];
            if(!empty($base_key[$name]['sub'])){ 
                $add_key['tag'][$name] = $cur_code;
            }else{
                $add_key[$name] = $cur_code;
            }
            $cur_key = self::SINGLE_KEY_PREFFIX.ml_tool_tag::single_key($name, $cur_code);
            
            if(empty($prev)){
                $prev = $cur_key;
                continue;
            }
            $comb_key = ml_tool_tag::comb_key($add_key);
            $destKey = self::COLLECT_KEY_PREFFIX.$comb_key['comb_key'];
            
            /*$aa = $this->zRange($prev,0,-1);
            $bb = $this->zRange($cur_key,0,-1);
            echo "<pre>";
            print_r($aa);
            print_r($bb);
            var_dump('aa'.$prev);
            var_dump('bb'.$cur_key);
            print_r(array_intersect($aa,$bb));exit;
            */
            
            if(!$this->exists($destKey)){
                //Tool_logger::monitorLog('guang_rdsgenerate', $destKey, Tool_logger::LOG_LEVEL_NOTICE );
                $starttime = ml_tool_time::get_microtime();
                $rs = $this->zInter($destKey, array($prev, $cur_key));
                $this->expireAt($destKey , time()+$this->cache_time);
                $endtime = ml_tool_time::get_microtime();
                //$usetime = bcsub($endtime, $starttime, 6);
                //Tool_logger::debugLog('guang_rdszinter', $destKey.' | '.$prev.' | '.$cur_key.' | '.$usetime);
                if(!$rs) return false;
            }
            $prev = $destKey;
            
        }
        return true;
    }
}
?>